package com.ghyf.mplay.bean;


import java.io.File;
import java.io.IOException;
import java.net.Socket;

import java.util.ArrayList;
import java.util.ListIterator;


import android.annotation.TargetApi;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.Time;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

import com.ghyf.mplay.WeakHandler;
import com.ghyf.mplay.application.CookieConstants;
import com.ghyf.mplay.application.UserInfoSingleton;
import com.ghyf.mplay.datatype.LocalPlayItem;
import com.ghyf.mplay.datatype.POS;
import com.ghyf.mplay.net.common.GData;
import com.ghyf.mplay.net.common.RecvBase;
import com.ghyf.mplay.net.log.LogTool;
import com.ghyf.mplay.util.LogUtil;

import com.ghyf.mplay.value.ConstantValue;
import com.ghyf.mplay.view.MVideo;

/**
 * 播放视频模块的信息类
 * @author 陈小红
 *
 */
public class VideoInfoView extends BaseModuleInfo {
	
	private static final String TAG="VideoInfo";
	private LocalPlayItem current_item; // 当前播放视频项
	private LocalPlayItem next_item; // 下一个播放视频项
	// 视频帧率，暂定25
	private int frameRate = 25; 
	private Uri uri;
	/**当前音量***/
	private int current=0;
	// <Is_Live >1</Is_Live >
	private boolean isLive=false; // 是否直播
	/**是否正在直播***/
	
//	private boolean isBreak;//直播是否中断
//	private boolean isFeedBack;//是否回传
	public static boolean isStop=false;

	// <Live_Channel>LiveChannel1(239.1.1.2:2860)</Live_Channel>
	private String live_channel;
	// <Live_Volume>>50</Live_Volume >
	private int live_volume; // 直播音量

	// <Local_List>
	// <Item Filename="Video1.mpg" Start_Time="03:00:00:00"
	// In_Point="00:00:00:30" Play_Length="01:00:00:00" Volume="45" />
	// <Item Filename="Video2.avi" Start_Time="04:00:00:00"
	// In_Point="00:00:10:30" Play_Length="01:30:00:00" Volume="55" />
	// <Item Filename="LiveChannel1" Start_Time="05:30:00:00"
	// In_Point="00:00:00:00" Play_Length="06:00:00:00" Volume="80" />
	// <Item Filename="Video3.vob" Start_Time="11:30:00:00"
	// In_Point="00:00:00:11" Play_Length="00:00:15:00" Volume="65" />
	// <Item Filename="Video4.mpg" Start_Time="11:30:15:00"
	// In_Point="00:00:00:30" Play_Length="01:00:00:00" Volume="75" />
	// </Local_List>

	private ArrayList<LocalPlayItem> local_list; // 本地视频播放列表。
	private int volume; // 本地视频播放音量
	private MVideo mVideo; // 播放视频的控件
	private ListIterator<LocalPlayItem> iterator;
	private String path;
	private AudioManager mAudioManager;
	private int max;
	@SuppressWarnings("unused")
	private Context mContext;
	/**
	 * 文件版本 File_Version CHAR 1 模块名称 Module_Name CHAR Video1 UID Module_UID INT
	 * GID Module_GIU INT 模块位置 Mudule_Pos POS - 是否直播 Is_Live BOOL TRUE 直播视频通道
	 * Live_Channel CHAR 直播通道1 (239.1.1.2:2860) 直播音量 Live_Volume INT 50 本地视频列表
	 * Local_List - 本地文件名 Filename CHAR 如文件名为LiveChannelXX，则表示播放第XX路直播视频 开始时间
	 * Start_Time FRAME 如开始时间为0，则表示非绝对时间播放； 00:00:00:00 开始帧 In_Point FRAME
	 * 00:00:00:00 播放时长 Play_Length FRAME 文件长度 音量 Volume INT，0-100 50
	 */

	/**
	 * 初始化并返回待显示控件对象
	 */
	@Override
	public MVideo getView(Context context) {
		mVideo = new MVideo(context);
		
		mContext=context;
		//设置控件基本属性
		mVideo.setModule_type(module_type);
		mVideo.setzOrder(zOrder);
		mVideo.setFile_version(file_version);
		mVideo.setModule_name(module_name);
		mVideo.setModule_uid(module_uid);
		mVideo.setModule_gid(module_gid);
		// 设置控件的位置
		initPosition(mVideo, pos);
		
		mAudioManager = (AudioManager) context
				.getSystemService(Context.AUDIO_SERVICE);
		max = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		startPlay();
		// 判断直播还是本地播放。
		addVideoListener(mVideo);
		
		isStop=false;
	
		return mVideo;
	}
	
	
	public void closeRtspThread(){
		 isCheck=false;
		if(checkThread!=null){
			checkThread.interrupt();
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
		}
	}

	
	
	boolean isCheck=true;
	Thread checkThread=null;
	/**
	 * 开始播放本地视频<br>
	 * 2013-11-28 下午3:09:54
	 */
	public void startPlay(){
//		isLive=UserInfoSingleton.getIslive().equals(ConstantValue.PLAY_LIVE)?true:false;
//		if (isLive) { 
//			//  直播
//			playLiveVideo1();
//			/**
//			 * 开启线程检测
////			 */
//			isCheck=true;
//			checkThread=new CheckPlayingThread();
//			checkThread.start();
//		} else { // 播放本地视频
			
			playLocalVideo();
//		}
	}
	private boolean isLocal=false;
	public boolean checkRtsp(){
		boolean flag=false;
		Socket socket=null;
			try{
			    socket=new Socket(GData.LIVEHOST, GData.LIVEPORT);
				flag=socket.isConnected();
				
			}catch(Exception e){
				flag=false;
				LogUtil.e(TAG, "检测直播地址:"+e);
			}finally{
				if(socket!=null){
					try {
						socket.close();
					} catch (IOException e) {
						
						e.printStackTrace();
					}
				}
			}
			
		return flag;
	}

	/**
	 * 播放本地视频<br>
	 * 2013-11-29 下午2:05:46
	 *
	 */
	private void playLocalVideo() {
		if(local_list==null)return;
		if(local_list.size()<=0)return;
		iterator = local_list.listIterator();
		// 如果有下个元素
		while (iterator.hasNext()) {
			// 获取第一个播放项
			LocalPlayItem item = iterator.next();
			// 获取当前时间毫秒值
			long currentTimeMillis = System.currentTimeMillis();
			Time current_time = new Time();
			current_time.set(currentTimeMillis);
			if (timeToMillis(current_time) >= item.getStart_frame()
					.toMillisecond(frameRate)) { // 如果当前时间晚于或等于本视频开始播放时间
				current_item = item;
				break; // 找到后退出循环
			}
		}
		if (current_item == null) { // 如果一个都没找到，则播放第一个
			while (iterator.hasPrevious()) {
				iterator.previous();
			}
			// 视频列表项播完了就再播第一项。
			current_item = iterator.next();
		}
		findNext();
		playVideo();
		System.gc();
	}
	
	int countTime=0;
	public void addVideoListener(final MVideo mVideo){
		
		
		mVideo.setOnCompletionListener(new OnCompletionListener() {
			@Override
			public void onCompletion(MediaPlayer mp) {
				LogUtil.i(TAG, "播放完当前视频项 isStop="+isStop+",isLive("+isLive+")");
				if(!isStop){
					LogTool.addPlayLog("视频","播放完毕","00:03:03:10","播放完当前视频");
//					if(!isLive){
						// 播放完当前视频项，停止播放以释放资源。
						mVideo.stopPlayback();
						// 将下一项设为当前项，
						current_item = next_item;
						// 并找到另一个下一项
						findNext();
						// 播放
						playVideo();
						
//					}else{
//						if(isLocal){
//							// 播放完当前视频项，停止播放以释放资源。
//							mVideo.stopPlayback();
//							// 将下一项设为当前项，
//							current_item = next_item;
//							// 并找到另一个下一项
//							findNext();
//							// 播放
//							playVideo();
//						}
//					}

				}
				
			}
		});

		
		// 播放视频一定长度后切换到下一个视频
		
		mVideo.setOnErrorListener(new OnErrorListener() { // 播放视频错误的监听。
			@Override
			public boolean onError(MediaPlayer mp, int what, int extra) {
				boolean isExigent=UserInfoSingleton.getIsExigent().equals("0")?true:false;
				if(isExigent){
					mVideo.stopPlayback();
				}else{
//					if(!isLive){
						// 播放完当前视频项，停止播放以释放资源。
						mVideo.stopPlayback();
						// 将下一项设为当前项，
						current_item = next_item;
						// 并找到另一个下一项
						findNext();
						// 播放
						playVideo();
						
//					}else{
//						if(isLocal){
//							// 播放完当前视频项，停止播放以释放资源。
//							mVideo.stopPlayback();
//							// 将下一项设为当前项，
//							current_item = next_item;
//							// 并找到另一个下一项
//							findNext();
//							// 播放
//							playVideo();
//						}
//					}

				}
			
				return true;
			}
		});
	}
	/**
	 * 初始化控件的位置
	 * 
	 * @param tv
	 *            被设置的控件
	 * @param pos
	 *            控件的位置
	 */
	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	void initPosition(View view, POS pos) {
		view.setX(pos.getLeft());
		view.setY(pos.getTop());
		view.setLayoutParams(new LayoutParams(pos.getWidth(), pos.getHeight()));
	}

	/**
	 * 找到下一个播放项。
	 */
	void findNext() {
		try{
			if(iterator==null){
				startPlay();
				return;
			}
			
			if (iterator.hasNext()) {
				next_item = iterator.next();
			} else {
				while (iterator.hasPrevious()) {
					iterator.previous();
				}
				// 视频列表项播完了就再播第一项。
				next_item = iterator.next();
			}
		}catch(Exception e){
			LogUtil.e(TAG, "find next error", e);
		}
		
	}
	MVideo liveVideo=null;
	Uri liveUri=null;
	/**
	 * 播放直播<br>
	 * 2013-11-28 下午3:12:49
	 *
	 */
	
	void playLiveVideo2() {
		
		uri = Uri.parse(GData.LIVEURL);
		mVideo.setVideoURI(uri);
		mVideo.setOnPreparedListener(new OnPreparedListener() {
			@Override
			public void onPrepared(MediaPlayer mp) {
				try{
					
					mHandler.sendEmptyMessage(9);
				
				}catch (Exception e) {
					
					LogUtil.e(TAG, "playLiveVideo出现异常",e);
				}
				
			}
		});
	}
	void playLiveVideo1() {
		
		mVideo.stopPlayback();
		LogUtil.i(TAG, "视频直播"+GData.LIVEURL);
		uri = Uri.parse(GData.LIVEURL);
		mVideo.setVideoURI(uri);
		mVideo.setOnPreparedListener(new OnPreparedListener() {
			@Override
			public void onPrepared(MediaPlayer mp) {
				try{
					
					mVideo.start();
				}catch (Exception e) {
					
					LogUtil.e(TAG, "playLiveVideo出现异常",e);
				}
				
			}
		});
	}
	
	
	public class ChangeVideoView implements Runnable{

		/* (non-Javadoc)
		 * @see java.lang.Runnable#run()
		 */
		@Override
		public void run() {
			
			mVideo.stopPlayback();
			mVideo=liveVideo;
//			setmVideo(liveVideo);
			
		}
		
	}
	/**
	 *  播放当前视频项
	 */
	void playVideo() {
		mVideo.stopPlayback();
		path = current_item.getFile().getPath();
		// 初始化事件文件的权限 判断如果是mkv 转为vlc播放
		
		uri = Uri.parse(path);
		mVideo.setVideoURI(uri);
	
		
		// 设置音量
		boolean isSet=UserInfoSingleton.getBoolean(CookieConstants.GlobalAudioVolume, false);
		boolean isMute=UserInfoSingleton.getBoolean(CookieConstants.GlobalAudioStatus, true);
	
		int volume=0;
		if(!isMute){
			if(isSet){
				volume=UserInfoSingleton.getInt(CookieConstants.AudioVolume, current_item.getVolume());
			}{
				volume=current_item.getVolume();
				UserInfoSingleton.putIntAndCommit(CookieConstants.AudioVolume,volume);
			}
		}
		LogUtil.i(TAG, "play volume("+volume+") path:"+path+",isSet="+isSet+",isMute="+isMute+" isExist="+	new File(path).exists());
		
		mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
				volume * max / 100, 0);
		// 设置首播放帧,根据首帧计算毫秒值。
				mVideo.setOnPreparedListener(new OnPreparedListener() {
					@Override
					public void onPrepared(MediaPlayer mp) {
						try{
							int inpoint = current_item.getIn_point().toMillisecond(
									frameRate);
							mVideo.seekTo(inpoint);
							mVideo.start();
						}catch (Exception e) {
							
							LogUtil.e(TAG, "出现异常",e);
						}
						
					}
				});
		
	}
	/**
	 * 接收控制中心对播放器视频的控制<br>
	 * 2014-7-23 下午2:27:11
	 * @param cmdId
	 * @param bundle
	 *
	 */
	public void receiveCmdControl(int cmdId,Bundle bundle){
		switch(cmdId){
		case 1:
			
			startPlay();
			break;
		case 9:
			mVideo.stopPlayback();
			mVideo.start();
			break;
		case RecvBase.CMD_CONTROL_PLAY:
			startPlay();
			break;
		case RecvBase.CMD_CONTROL_STOP:
			mVideo.stopPlayback();
			break;
		case RecvBase.CMD_CONTROL_REPLAY:
			mVideo.start();
			break;
		case RecvBase.CMD_CONTROL_PAUSEPLAY:
			mVideo.pause();
			
			break;
		case RecvBase.CMD_CONTROL_SETVOLUME:
			byte v=bundle.getByte("volume");
			mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 
					v* max / 100, 0);
			
			break;
		case RecvBase.CMD_CONTROL_SOUNDON:
			UserInfoSingleton.putIntAndCommit(CookieConstants.AudioStatus,ConstantValue.AUDIOSTATUS_YES);
			if(current!=0){
				mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 
						current, 0);
			}
			break;
		case RecvBase.CMD_CONTROL_SOUNDMUTE:
			
			UserInfoSingleton.putIntAndCommit(CookieConstants.AudioStatus,ConstantValue.AUDIOSTATUS_NO);
			current = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC );
			mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 
			0, 0);
			break;
			
		}
	}
	
	
	 private static class VideoViewHandler extends WeakHandler<VideoInfoView> {
		 public VideoViewHandler(VideoInfoView owner) {
	            super(owner);
	        
		 }
		 
		   @Override
			public void handleMessage(Message msg) {
			         
			  VideoInfoView activity = getOwner();
			  if(activity == null) return;
			        	
			  LogUtil.i(TAG, "接收CMD");
				switch(msg.what){
				case 1:
					
					activity.startPlay();
					break;
				case 9:
					activity.mVideo.stopPlayback();
					activity.mVideo.start();
					break;
				case RecvBase.CMD_CONTROL_PLAY:
					activity.startPlay();
					break;
				case RecvBase.CMD_CONTROL_STOP:
					activity.mVideo.stopPlayback();
					break;
				case RecvBase.CMD_CONTROL_REPLAY:
					activity.mVideo.start();
					break;
				case RecvBase.CMD_CONTROL_PAUSEPLAY:
					activity.mVideo.pause();
					
					break;
				case RecvBase.CMD_CONTROL_SETVOLUME:
					byte v=msg.getData().getByte("volume");
					activity.mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 
							v* activity.max / 100, 0);
					
					break;
				case RecvBase.CMD_CONTROL_SOUNDON:
					if(activity.current!=0){
						activity.mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 
								activity.current, 0);
					}
					break;
				case RecvBase.CMD_CONTROL_SOUNDMUTE:
				
					activity.current = activity.mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC );
					activity.mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 
					0, 0);
					break;
				case RecvBase.CMD_CONTROL_PLAYSTREAM:
					/**
					 * 直播
					 */
					isStop=false;
					String flag=UserInfoSingleton.getIslive();
					
					if(flag.equals(ConstantValue.PLAY_LIVE)){
						LogUtil.i(TAG, "当前处于直播状态,不要重复点击直播");
						return;
					}else{
						UserInfoSingleton.setIslive(ConstantValue.PLAY_LIVE);
						activity.startPlay();
					}
					
				
					
					break;
				case RecvBase.CMD_CONTROL_PLAYLOCAL:
					/**
					 * 本地
					 */
					String flag1=UserInfoSingleton.getIslive();
					isStop=false;
					if(flag1.equals(ConstantValue.PLAY_LOCAL)){
						LogUtil.i(TAG, "当前处于本地状态,不要重复点击本地");
						return;
					}else{
						activity.closeRtspThread();
						UserInfoSingleton.setIslive(ConstantValue.PLAY_LOCAL);
						activity.startPlay();
						
					}
					
					break;
				case RecvBase.CMD_CONTROL_RESET:
					
//					CommonUtil.reboot(activity);
					break;
				case RecvBase.CMD_STATUS_GETCURDIAPLAY:
//					final CurDisplayData data=(CurDisplayData)msg.getData().getSerializable(ConstantValue.EXTRA_OBJ);
//					/**
//					 * 得到视频回传的ip port,下面进行传输
//					 */
//					byte cmdParam=data.getCmdParam();
//					switch(cmdParam){
//					case (byte)0:
//						isFeedBack=false;
//						break;
//					case (byte)1:
//						isFeedBack=true;
//						new Thread(new Runnable() {
//							
//							@Override
//							public void run() {
//								//  待处理 视频回传
////								videoFeedBack(data);
//							}
//						}).start();
//						
//						break;
//					}
					
					break;
				}
				
				super.handleMessage(msg);
		   }
	 }

	private final Handler mHandler=new VideoViewHandler(this);
	
	
	
	/**
	 * 计算某个时间点的时、分、秒对应的毫秒值
	 * 
	 * @param time  时间
	 * 
	 * @return 时间的时分秒对应的毫秒值
	 */
	private int timeToMillis(Time time) {
		return time.hour * 60 * 60 * 1000 + time.minute * 60 * 1000
				+ time.second * 1000;
	}


	public int getVolume() {
		return volume;
	}

	public void setVolume(int volume) {
		this.volume = volume;
	}

	public boolean isLive() {
		return isLive;
	}

	public void setLive(boolean isLive) {
		this.isLive = isLive;
	}

	public String getLive_channel() {
		return live_channel;
	}

	public void setLive_channel(String live_channel) {
		this.live_channel = live_channel;
	}

	public int getLive_volume() {
		return live_volume;
	}

	public void setLive_volume(int live_volume) {
		this.live_volume = live_volume;
	}

	public ArrayList<LocalPlayItem> getLocal_list() {
		return local_list;
	}

	public void setLocal_list(ArrayList<LocalPlayItem> local_list) {
		this.local_list = local_list;
	}
	/**
	 * @return the mVideo
	 */
	public MVideo getmVideo() {
		return mVideo;
	}
	/**
	 * @param mVideo the mVideo to set
	 */
	public void setmVideo(MVideo mVideo) {
		this.mVideo = mVideo;
	}

	
}
